#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MQTTClient.h"

#define ADDRESS   "tcp://192.168.12.77:1883"
#define CLIENTID  "9b6c9c71-009a-4656-8876-c94abf7edf68" 
#define TOPIC_PULL    "pull"
#define TOPIC_PUSH    "push"
#define PAYLOAD   "Hello World!"
#define QOS     1
#define TIMEOUT   10000L

static MQTTClient_message pubmsg = MQTTClient_message_initializer;

void delivered(void *context, MQTTClient_deliveryToken dt)
{
  printf("Message with token value %d delivery confirmed\n", dt);
}

int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
  printf("Message arrived\n");
  printf("   topic: %s\n", topicName);
  printf("  message: %.*s\n", message->payloadlen, (char*)message->payload);
  MQTTClient_freeMessage(&message);
  MQTTClient_free(topicName);
  return 1;
}

void connlost(void *context, char *cause)
{
  printf("\nConnection lost\n");
  printf("   cause: %s\n", cause);
}

int main(int argc, char* argv[])
{
  MQTTClient client;
  MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
  int rc;

  if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID,
    MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS)
  {
    printf("Failed to create client, return code %d\n", rc);
    rc = EXIT_FAILURE;
    goto exit;
  }

  if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS)
  {
    printf("Failed to set callbacks, return code %d\n", rc);
    rc = EXIT_FAILURE;
    goto destroy_exit;
  }

  if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
  {
    printf("Failed to connect, return code %d\n", rc);
    rc = EXIT_FAILURE;
    goto destroy_exit;
  }

  printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
     "Press Q<Enter> to quit\n\n", TOPIC_PULL, CLIENTID, QOS);
  if ((rc = MQTTClient_subscribe(client, TOPIC_PULL, QOS)) != MQTTCLIENT_SUCCESS)
  {
    printf("Failed to subscribe, return code %d\n", rc);
    rc = EXIT_FAILURE;
  }
  else
  {
    int ch;
    do
    {
        ch = getchar();
    } while (ch!='Q' && ch != 'q');

    if ((rc = MQTTClient_unsubscribe(client, TOPIC_PULL)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to unsubscribe, return code %d\n", rc);
        rc = EXIT_FAILURE;
    }
}

  pubmsg.payload = PAYLOAD;
  pubmsg.payloadlen = (int)strlen(PAYLOAD);
  pubmsg.qos = QOS;
  if ((rc = MQTTClient_publishMessage(client, TOPIC_PUSH, &pubmsg, NULL)) != MQTTCLIENT_SUCCESS)
  {
    printf("Failed to publish message, return code %d\n", rc);
    rc = EXIT_FAILURE;
  }

  if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS)
  {
    printf("Failed to disconnect, return code %d\n", rc);
    rc = EXIT_FAILURE;
}
return rc;

destroy_exit:
  MQTTClient_destroy(&client);
exit:
  return rc;
}